import { defineStore } from 'pinia'
import { ref, watch } from 'vue'
import mitt from 'mitt'
import { useTokenStore } from './token'

/**
 * WebSocket 消息接口
 */
interface WebSocketMessage<T> {
  path: string
  data: T
}

export const useWebSocketStore = defineStore('websocket', () => {
  const isConnected = ref(false)
  const socket = ref<WebSocket | null>(null)
  const tokenStore = useTokenStore()
  const wsUrl = import.meta.env.VITE_WS_URL
  const emitter = mitt()
  const connect = () => {
    if (!tokenStore.token.accessToken) return

    socket.value = new WebSocket(`${wsUrl}?token=${tokenStore.token.accessToken}`)

    socket.value.onopen = () => {
      isConnected.value = true
      // 连接成功后初始化消息监听
      socket.value!.onmessage = (event) => {
        try {
          const message = JSON.parse(event.data) as WebSocketMessage<any>
          emitter.emit(message.path, message.data)
        } catch (error) {
          console.error('WebSocket message parse error:', error)
        }
      }
    }

    socket.value.onclose = () => {
      isConnected.value = false
      socket.value = null
    }

    socket.value.onerror = () => {
      isConnected.value = false
      socket.value = null
    }
  }

  const disconnect = () => {
    if (!socket.value) return
    socket.value.close()
    socket.value = null
    isConnected.value = false
  }

  // 确保在应用初始化时创建store
  const initWebSocket = () => {
    // 保存当前的token，用于与新token对比
    let prevToken = tokenStore.token.accessToken

    watch(
      () => tokenStore.token.accessToken,
      (newToken) => {
        // 检测 token 是否发生变化
        const tokenChanged = newToken !== prevToken
        // 未连接且有新 token 时连接
        if (newToken && !isConnected.value) {
          connect()
        }
        // 已连接但无 token 时断开
        else if (!newToken && isConnected.value) {
          disconnect()
        }
        // 已连接且 token 发生变化时断开重连
        else if (newToken && isConnected.value && tokenChanged) {
          disconnect()
          // 添加小延迟再连接，避免立即连接可能导致的问题
          setTimeout(() => connect(), 1000)
        }

        // 更新前一个 token 的值
        prevToken = newToken
      },
      { immediate: true }
    )
  }

  initWebSocket()

  // 发送消息
  const send = <T>(path: string, data: T) => {
    if (socket.value && socket.value.readyState === WebSocket.OPEN) {
      const message = {
        path,
        data,
        timestamp: Date.now()
      }
      socket.value.send(JSON.stringify(message))
    }
  }

  // 监听消息
  const on = <T>(path: string, callback: (message: T extends unknown ? any : T) => void) => {
    emitter.on(path, callback as (event: any) => void)
  }

  // 取消消息监听
  const off = (path: string, callback?: (event: any) => void) => {
    emitter.off(path, callback)
  }

  return {
    isConnected,
    send,
    on,
    off
  }
})
